package propcalc_lang.ast;

import java.util.*;

/** Una variable proposicional, representada por su identificador.
 *  @author Leonardo Val 
 */
public class Variable extends Proposition {
	public final String identifier;
	
	public Variable(String identifier) {
		this.identifier = identifier;
	}

	@Override public String unparse() {
		return identifier;
	}

	public static Variable generate(Random random, int min, int max) {
		return new Variable(((char)(random.nextInt('z' - 'a' + 1) + 'a')) +"");
	}
	
	@Override public Set<String> variables(Set<String> vars) {
		if (!vars.contains(identifier)){
			vars.add(identifier);
		}				
		return vars;
	}
	
	@Override public Proposition substitution(Map<String, Proposition> replacements) {
		if(replacements.containsKey(identifier)){			
			return replacements.get(identifier);
		}		
		return new Variable(identifier);
	}
	
	@Override public boolean match(Proposition pattern, Map<String, Proposition> replacements) {		
		if(pattern instanceof Variable){
			Variable v = (Variable) pattern;
			if (replacements.containsKey(v.identifier)){
				return this.equals(replacements.get(v.identifier));
			}else{
				replacements.put(v.identifier, this);
				return true;
			}			
		}
		return false;
	}
	
	@Override public String toString() {
		return "Variable(\""+ identifier +"\")";
	}

	@Override public int hashCode() {
		return 31 + ((identifier == null) ? 0 : identifier.hashCode());
	}

	@Override public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Variable other = (Variable) obj;
		if (identifier == null) {
			if (other.identifier != null)
				return false;
		} else if (!identifier.equals(other.identifier))
			return false;
		return true;
	}

}
